<!DOCTYPE html>
<html lang="zh-CN">





<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/apple-touch-icon.png">
  <link rel="icon" type="image/png" href="/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="description" content="">
  <meta name="author" content="yhs0092">
  <meta name="keywords" content="TLS,OpenSSL,keytool,java">
  <title>使用keytool和OpenSSL自行签发TLS证书 ~ 遥·海·时 的博客</title>

  <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/5.10.2/css/all.min.css"  >
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"  >
<link rel="stylesheet" href="https://cdn.staticfile.org/mdbootstrap/4.8.9/css/mdb.min.css"  >
<link rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/3.0.1/github-markdown.min.css"  >

<link rel="stylesheet" href="//at.alicdn.com/t/font_1067060_qzomjdt8bmp.css">



  <link rel="stylesheet" href="/lib/prettify/github-v2.min.css"  >

<link rel="stylesheet" href="/css/main.css"  >


  <link rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css"  >


<meta name="generator" content="Hexo 4.2.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>遥·海·时 的博客</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          <li class="nav-item">
            <a class="nav-link" href="/">Home</a>
          </li>
        
          
          
          <li class="nav-item">
            <a class="nav-link" href="/archives/">Archives</a>
          </li>
        
          
          
          <li class="nav-item">
            <a class="nav-link" href="/categories/">Categories</a>
          </li>
        
          
          
          <li class="nav-item">
            <a class="nav-link" href="/tags/">Tags</a>
          </li>
        
          
          
          <li class="nav-item">
            <a class="nav-link" href="/about/">About</a>
          </li>
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>


</nav>

    <div class="view intro-2" id="background"
         style="background: url('/img/post-banner.jpg')no-repeat center center;
           background-size: cover;
           background-attachment: fixed;">
      <div class="full-bg-img">
        <div class="mask rgba-black-light flex-center">
          <div class="container text-center white-text fadeInUp">
            <span class="h2" id="subtitle">
              
            </span>

            
              <br>
              
                <p class="mt-3">
                  <i class="fas fa-calendar-alt" aria-hidden="true"></i>&nbsp;
                  星期三, 十一月 13日 2019, 9:28 上午
                </p>
              

              <p>
                
                  
                  &nbsp;<i class="far fa-chart-bar"></i>
                  <span class="post-count">
                    2.4k 字
                  </span>&nbsp;
                

                
                  
                  &nbsp;<i class="far fa-clock"></i>
                  <span class="post-count">
                      11 分钟
                  </span>&nbsp;
                

                
                  <!-- 不蒜子统计文章PV -->
                  
                  &nbsp;<i class="far fa-eye" aria-hidden="true"></i>&nbsp;
                  <span id="busuanzi_container_page_pv">
                    <span id="busuanzi_value_page_pv"></span> 次
                  </span>&nbsp;
                
              </p>
            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="py-5 z-depth-3" id="board">
        <div class="post-content mx-auto" id="post">
          <div class="markdown-body">
            <p>本文主要说明如何使用JDK自带的keytool和OpenSSL自行签发TLS证书，方便进行本地开发测试。</p>
<a id="more"></a>
<h1 id="使用keytool和OpenSSL自行签发TLS证书"><a href="#使用keytool和OpenSSL自行签发TLS证书" class="headerlink" title="使用keytool和OpenSSL自行签发TLS证书"></a>使用keytool和OpenSSL自行签发TLS证书</h1><blockquote>
<p>本文适用于Java微服务场景下，自行创建CA和签发TLS证书，方便自行开发调试，不适合于生产条件。<br>最终目录结构：</p>
<pre><code>workdir    // 这是本文的工作目录，可以随意自定义
|- ca      // CA证书所在目录（根证书）
|- cert    // 服务端/客户端身份证书所在目录
|- trust   // 信任证书所在目录</code></pre></blockquote>
<h2 id="基本说明"><a href="#基本说明" class="headerlink" title="基本说明"></a>基本说明</h2><p>创建一份证书，基本步骤有三步：</p>
<ol>
<li><p>创建一份自己的私钥文件</p>
<p>理论上讲这份私钥文件，必须保密，不能让其他人获取到内容的。</p>
</li>
<li><p>生成一份“证书请求文件”</p>
<p>生成证书请求文件的后缀一般是<code>.csr</code>(Certificate Signing Request)。<br>如果你要购买一份生产环境使用的TLS证书，就需要签一份csr文件发给CA，让他们根据你的csr文件签发证书给你。</p>
</li>
<li><p>签发证书</p>
<p>由于本文创建的证书只是用于开发、测试目的，所以不需要向CA购买证书，而是自行创建CA证书，再用CA证书签发TLS证书。</p>
</li>
</ol>
<p>在创建完TLS证书（身份证书）后，我们还可以使用JDK自带的<code>keytool</code>创建一份信任证书，这样可以让这套证书用于Java服务TLS对端认证的测试场景。</p>
<hr>
<p>环境信息：</p>
<ul>
<li>OpenJDK 1.8.0_191</li>
<li>OpenSSL 1.1.0g</li>
</ul>
<h2 id="创建CA"><a href="#创建CA" class="headerlink" title="创建CA"></a>创建CA</h2><p>跳转到 ca 目录下。由于是自己当CA签证书，所以要先创建好CA的证书。</p>
<h3 id="创建CA证书私钥"><a href="#创建CA证书私钥" class="headerlink" title="创建CA证书私钥"></a>创建CA证书私钥</h3><p>命令<code>openssl genrsa -aes128 -out ca.key 4096</code>表示以aes128加密的方式生成一个长度为4096bit的RSA私钥文件。<br><strong>注意</strong>：创建过程中<code>openssl</code>会让你输入私钥文件的密码，进行加密。</p>
<pre><code class="shell">workdir/ca# openssl genrsa -aes128 -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
.............................................................................++
.....................................++
e is 65537 (0x010001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:

workdir/ca# ll
total 12
drwxr-xr-x 2 root root 4096 Nov 12 23:09 ./
drwxr-xr-x 3 root root 4096 Nov 12 23:08 ../
-rw------- 1 root root 3326 Nov 12 23:09 ca.key</code></pre>
<p>执行完成后当前目录下应该生成了一份<code>ca.key</code>文件，这份文件是私钥，应该保密存储。</p>
<h3 id="创建CA证书"><a href="#创建CA证书" class="headerlink" title="创建CA证书"></a>创建CA证书</h3><p>命令<code>openssl req -new -x509 -key ca.key -out ca.crt -days 3650</code> 的含义为，使用CA私钥（<code>-key ca.key</code>），创建一份CA证书（<code>-out ca.crt</code>），有效时间为3650天（<code>-days 3650</code>）。<br><strong>注意</strong>：这一步需要输入CA私钥文件的密码，即上一步创建<code>ca.key</code>文件时设置的密码。</p>
<pre><code class="shell">workdir/ca# openssl req -new -x509 -key ca.key -out ca.crt -days 3650
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &#39;.&#39;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Guangdong
Locality Name (eg, city) []:Shenzhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:xxx
Organizational Unit Name (eg, section) []:xxx
Common Name (e.g. server FQDN or YOUR name) []:xxx
Email Address []:xxx@xxx.xxx

workdir/ca# ll
total 16
drwxr-xr-x 2 root root 4096 Nov 12 23:21 ./
drwxr-xr-x 3 root root 4096 Nov 12 23:08 ../
-rw-r--r-- 1 root root 2069 Nov 12 23:21 ca.crt
-rw------- 1 root root 3326 Nov 12 23:09 ca.key</code></pre>
<p>创建证书过程中需要输入所在地、公司名称，因为本文生成证书的目的只是开发测试，所以这里是随便填写的。执行完成后能够看到一份<code>ca.crt</code>文件。</p>
<h2 id="签发身份证书"><a href="#签发身份证书" class="headerlink" title="签发身份证书"></a><span id="签发身份证书">签发身份证书</span></h2><p>跳转到 cert 目录下。</p>
<h3 id="生成私钥"><a href="#生成私钥" class="headerlink" title="生成私钥"></a>生成私钥</h3><p>操作和刚才生成CA私钥一样，不再赘述。</p>
<pre><code class="shell">workdir/cert# openssl genrsa -aes128 -out server.key 4096
Generating RSA private key, 4096 bit long modulus
.............................++
........................................................................................................................................................................................................................++
e is 65537 (0x010001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

workdir/cert# ll
total 12
drwxr-xr-x 2 root root 4096 Nov 12 23:32 ./
drwxr-xr-x 4 root root 4096 Nov 12 23:31 ../
-rw------- 1 root root 3326 Nov 12 23:32 server.key</code></pre>
<h3 id="创建证书请求文件"><a href="#创建证书请求文件" class="headerlink" title="创建证书请求文件"></a>创建证书请求文件</h3><p>创建证书请求文件需要用到上一步创建的私钥文件（<code>server.key</code>)。<code>A challenge password</code>和<code>An optional company name</code>那里可以直接敲回车跳过不填。</p>
<pre><code class="shell">workdir/cert# openssl req -new -key server.key -out server.csr
Enter pass phrase for server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &#39;.&#39;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Guangdong
Locality Name (eg, city) []:Shenzhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:xxx
Organizational Unit Name (eg, section) []:xxx
Common Name (e.g. server FQDN or YOUR name) []:xxx
Email Address []:xxx@xxx.xxx

Please enter the following &#39;extra&#39; attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

workdir/cert# ll
total 16
drwxr-xr-x 2 root root 4096 Nov 12 23:42 ./
drwxr-xr-x 4 root root 4096 Nov 12 23:31 ../
-rw-r--r-- 1 root root 1724 Nov 12 23:42 server.csr
-rw------- 1 root root 3326 Nov 12 23:32 server.key</code></pre>
<p>执行完成后目录下会出现一份<code>server.csr</code>文件。</p>
<h3 id="签发证书文件"><a href="#签发证书文件" class="headerlink" title="签发证书文件"></a>签发证书文件</h3><p>注意这里执行的命令会指定使用上面创建的CA证书以及CA私钥文件（<code>-CA ../ca/ca.crt -CAkey ../ca/ca.key</code>），有效期为3650天，输出文件为<code>server.crt</code>。</p>
<pre><code class="shell">workdir/cert# openssl x509 -req -days 3650 -in server.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -CAcreateserial -out server.crt
Signature ok
subject=C = CN, ST = Guangdong, L = Shenzhen, O = xxx, OU = xxx, CN = xxx, emailAddress = xxx@xxx.xxx
Getting CA Private Key
Enter pass phrase for ../ca/ca.key:

workdir/cert# ll
total 24
drwxr-xr-x 2 root root 4096 Nov 12 23:49 ./
drwxr-xr-x 4 root root 4096 Nov 12 23:31 ../
-rw-r--r-- 1 root root 1948 Nov 12 23:49 server.crt
-rw-r--r-- 1 root root 1724 Nov 12 23:42 server.csr
-rw------- 1 root root 3326 Nov 12 23:32 server.key
-rw-r--r-- 1 root root   17 Nov 12 23:49 .srl</code></pre>
<h3 id="将crt证书转换为PKCS12格式"><a href="#将crt证书转换为PKCS12格式" class="headerlink" title="将crt证书转换为PKCS12格式"></a>将crt证书转换为PKCS12格式</h3><p>上一步其实已经成功创建出身份证书了（就是<code>server.crt</code>），这里把该文件转换成PKCS12格式，方便Java服务使用。<br><strong>注意</strong>：这一步需要输入私钥<code>server.key</code>的密码，导出证书的密码可由读者自行设置。</p>
<pre><code class="shell">workdir/cert# openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12
Enter pass phrase for server.key:
Enter Export Password:
Verifying - Enter Export Password:

workdir/cert# ll
total 32
drwxr-xr-x 2 root root 4096 Nov 13 00:09 ./
drwxr-xr-x 5 root root 4096 Nov 12 23:52 ../
-rw-r--r-- 1 root root 1948 Nov 12 23:49 server.crt
-rw-r--r-- 1 root root 1724 Nov 12 23:42 server.csr
-rw------- 1 root root 3326 Nov 12 23:32 server.key
-rw------- 1 root root 4157 Nov 13 00:09 server.p12
-rw-r--r-- 1 root root   17 Nov 12 23:49 .srl</code></pre>
<h2 id="创建信任证书"><a href="#创建信任证书" class="headerlink" title="创建信任证书"></a>创建信任证书</h2><p>跳转到trust目录。</p>
<h3 id="创建keystore文件"><a href="#创建keystore文件" class="headerlink" title="创建keystore文件"></a>创建keystore文件</h3><p>使用keytool新建一份 keystore 文件，这个文件会被用作信任证书：</p>
<pre><code class="shell">workdir/trust# keytool -genkeypair -alias trust -keystore trust.jks -keyalg RSA -sigalg SHA1withRSA
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  xxx
What is the name of your organizational unit?
  [Unknown]:  xxx
What is the name of your organization?
  [Unknown]:  xxx
What is the name of your City or Locality?
  [Unknown]:  Shenzhen
What is the name of your State or Province?
  [Unknown]:  Guangdong
What is the two-letter country code for this unit?
  [Unknown]:  CN
Is CN=xxx, OU=xxx, O=xxx, L=Shenzhen, ST=Guangdong, C=CN correct?
  [no]:  yes</code></pre>
<p><strong>注意</strong>：创建过程中<code>keytool</code>会要求你给这份 keystore 文件设置密码。<br>执行成功的话会在trust目录下生成一份 keystore 文件：</p>
<pre><code>workdir/trust# ll
total 12
drwxr-xr-x 2 root root 4096 Nov 12 23:54 ./
drwxr-xr-x 5 root root 4096 Nov 12 23:52 ../
-rw-r--r-- 1 root root 2557 Nov 12 23:54 trust.jks</code></pre><h3 id="导入CA证书"><a href="#导入CA证书" class="headerlink" title="导入CA证书"></a>导入CA证书</h3><p>将前文创建的CA证书导入到<code>trust.jks</code>文件中，这样，使用此CA证书签发的TLS证书就都被这份 keystore 文件信任了。<br><strong>注意</strong>：导入过程需要输入<code>trust.jks</code>文件的密码，也可以在命令中使用<code>-storepass</code>参数输入密码。</p>
<pre><code class="shell">workdir/trust# keytool -import -file ../ca/ca.crt -keystore trust.jks
Enter keystore password:
Owner: EMAILADDRESS=xxx@xxx.xxx, CN=xxx, OU=xxx, O=xxx, L=Shenzhen, ST=Guangdong, C=CN
Issuer: EMAILADDRESS=xxx@xxx.xxx, CN=xxx, OU=xxx, O=xxx, L=Shenzhen, ST=Guangdong, C=CN
Serial number: d66ebd9ea172d18a
Valid from: Tue Nov 12 23:21:27 CST 2019 until: Fri Nov 09 23:21:27 CST 2029
Certificate fingerprints:
         SHA1: A2:19:67:E6:D2:A2:6E:7E:E6:C8:15:2C:CD:F7:48:70:EF:85:03:8D
         SHA256: 58:FF:94:50:E4:22:73:A3:8C:77:7D:6E:06:38:D6:98:0D:0D:58:83:44:46:93:CB:4E:56:48:AE:AC:41:63:F0
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 95 4E 27 2B 65 7C E6 8F   E3 F8 46 7D 09 3B 44 ED  .N&#39;+e.....F..;D.
0010: 08 60 94 00                                        .`..
]
]

#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 95 4E 27 2B 65 7C E6 8F   E3 F8 46 7D 09 3B 44 ED  .N&#39;+e.....F..;D.
0010: 08 60 94 00                                        .`..
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore</code></pre>
<p>执行成功后，可以运行<code>keytool -list -v -keystore trust.jks</code>命令查看导入的内容。</p>
<h2 id="完成"><a href="#完成" class="headerlink" title="完成"></a>完成</h2><p>至此，证书生成工作就完成了。对于Java服务，可以使用<code>cert</code>目录下的<code>server.p12</code>作为身份证书，<code>trust</code>目录下的<code>trust.jks</code>作为信任证书来启动服务。<br><code>trust.jks</code>信任了签发<code>server.p12</code>的CA证书，所以客户端、服务端程序开启TLS对端认证进行测试时，可以使用同一套证书，<br>也可以重复<a href="#签发身份证书">签发身份证书</a>的步骤签发多套证书。</p>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><h3 id="如何查看证书"><a href="#如何查看证书" class="headerlink" title="如何查看证书"></a>如何查看证书</h3><ul>
<li><p>使用keytool查看crt证书：</p>
<p><code>keytool -printcert -v -file server.crt</code></p>
</li>
<li><p>使用keytool查看keystore文件：</p>
<p><code>keytool -list -v -keystore trust.jks</code></p>
</li>
<li><p>使用OpenSSL查看crt证书：</p>
<p><code>openssl x509 -in server.crt -text -noout</code></p>
</li>
</ul>
<h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ul>
<li><a href="https://www.cnblogs.com/yjmyzz/p/openssl-tutorial.html" target="_blank" rel="noopener">https://www.cnblogs.com/yjmyzz/p/openssl-tutorial.html</a></li>
<li><a href="https://sites.google.com/site/ddmwsst/create-your-own-certificate-and-ca" target="_blank" rel="noopener">https://sites.google.com/site/ddmwsst/create-your-own-certificate-and-ca</a></li>
<li><a href="https://blog.csdn.net/defonds/article/details/85098684" target="_blank" rel="noopener">https://blog.csdn.net/defonds/article/details/85098684</a></li>
<li><a href="https://blog.csdn.net/linvo/article/details/9150607" target="_blank" rel="noopener">https://blog.csdn.net/linvo/article/details/9150607</a></li>
</ul>

            <hr>
          </div>
          <br>
          <div>
            <p>
            
              <span>
                <i class="iconfont icon-inbox"></i>
                
                  <a class="hover-with-bg" href="/categories/%E8%BD%AF%E4%BB%B6%E6%8A%80%E6%9C%AF">软件技术</a>
                  &nbsp;
                
              </span>&nbsp;&nbsp;
            
            
              <span>
                <i class="iconfont icon-tag"></i>
                
                  <a class="hover-with-bg" href="/tags/TLS">TLS</a>
                
                  <a class="hover-with-bg" href="/tags/OpenSSL">OpenSSL</a>
                
                  <a class="hover-with-bg" href="/tags/keytool">keytool</a>
                
                  <a class="hover-with-bg" href="/tags/java">java</a>
                
              </span>
            
            </p>
            
              <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a href="https://zh.wikipedia.org/wiki/Wikipedia:CC_BY-SA_3.0%E5%8D%8F%E8%AE%AE%E6%96%87%E6%9C%AC" target="_blank" rel="nofollow noopener noopener">CC BY-SA 3.0协议</a> 。转载请注明出处！</p>
            
          </div>
        </div>
      </div>
    </div>
    <div class="d-none d-lg-block col-lg-2 toc-container">
      
  <div id="toc">
    <p class="h4"><i class="far fa-list-alt"></i>&nbsp;目录</p>
    <div id="tocbot"></div>
  </div>

    </div>
  </div>
</div>

<!-- custom -->


<!-- Comments -->
<div class="col-lg-7 mx-auto nopadding-md">
  <div class="container comments mx-auto" id="comments">
    
  </div>
</div>

    
  </main>

  
    <a class="z-depth-1" id="scroll-top-button" href="#" role="button">
      <i class="fa fa-chevron-up scroll-top-arrow" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  <footer class="mt-5">
  <div class="text-center py-3">
    <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><b>Hexo</b></a>
    <i class="iconfont icon-love"></i>
    <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"> <b>Fluid</b></a>
    <br>

    
  
    <!-- 不蒜子统计PV -->
    
    &nbsp;<span id="busuanzi_container_site_pv">总访问量 
          <span id="busuanzi_value_site_pv"></span> 次</span>&nbsp;
  
  
    <!-- 不蒜子统计UV -->
    
    &nbsp;<span id="busuanzi_container_site_uv">总访客数 
            <span id="busuanzi_value_site_uv"></span> 人</span>&nbsp;
  
  <br>



    

  </div>
</footer>

<!-- SCRIPTS -->
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js" ></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js" ></script>
<script src="https://cdn.staticfile.org/mdbootstrap/4.8.9/js/mdb.min.js" ></script>
<script src="/js/main.js" ></script>


  <script src="/js/lazyload.js" ></script>



  
    <script src="https://cdn.staticfile.org/tocbot/4.8.0/tocbot.min.js" ></script>
  
  <script src="/js/post.js" ></script>



  <script src="https://cdn.staticfile.org/smooth-scroll/16.1.0/smooth-scroll.min.js" ></script>



  <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>


<!-- Plugins -->


  

  

  

  

  




  <script src="https://cdn.staticfile.org/prettify/r298/prettify.min.js" ></script>
  <script>
    $(document).ready(function () {
      $('pre').addClass('prettyprint  linenums');
      prettyPrint();
    })
  </script>



  <script src="https://cdn.staticfile.org/typed.js/2.0.10/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "使用keytool和OpenSSL自行签发TLS证书&nbsp;",
      ],
      cursorChar: "_",
      typeSpeed: 70,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script src="https://cdn.staticfile.org/anchor-js/4.2.0/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "left",
      visible: "false",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script src="/js/local-search.js" ></script>
  <script>
    var path = "/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      getSearchFile(path);
      this.onclick = null
    }
  </script>



  <script src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <script>
    $("#post img:not(.no-zoom img, img[no-zoom])").each(
      function () {
        var element = document.createElement("a");
        $(element).attr("data-fancybox", "images");
        $(element).attr("href", $(this).attr("src"));
        $(this).wrap(element);
      }
    );
  </script>







</body>
</html>
